package edu.hku.c3330.hkucompanion.manager;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import edu.hku.c3330.hkucompanion.manager.DataManager.EventDbConstants;
import edu.hku.c3330.hkucompanion.manager.DataManager.RecurrenceDbConstants;
import edu.hku.c3330.hkucompanion.manager.Event.RecurrenceDateTime;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.widget.Adapter;
import android.widget.ListAdapter;

public class EventManager 
{
	static Context context;
	public static void setContext(Context context)
	{
		EventManager.context = context; 
	}
	
	public static ListAdapter getEventListAdapter()
	{
		return null;
	}
	
	public static Adapter getCalendarAdapter()
	{
		return null;
	}
	
	/*
	public static long addEvent(Event event)
	{



		return lastRowId;
	}
	*/
	
	public static List<Event> sortEventsByName(SortMethod method, List<Event> events)
	{
		return null;
	}
	
	public static List<Event> getAllEvents(boolean customEventOnly, String orderBy)
	{
		SQLiteDatabase db = DataManager.getInstance(context).getReadableDatabase();
		Cursor cur  = db.query(
			EventDbConstants.TABLE_NAME,
			new String[]{
				EventDbConstants._ID,
				EventDbConstants.TITLE,
				EventDbConstants.DESC,
				EventDbConstants.LOCATION,
				EventDbConstants.IS_SINGLE,
				EventDbConstants.IS_CUSTOM,
				EventDbConstants.PRIORITY,
				EventDbConstants.START,
				EventDbConstants.END
			},customEventOnly?(EventDbConstants.IS_CUSTOM + " = 1"):null, null, null, null, orderBy
		);
		return extractEventFromCursor(db, cur);
	}
	
	public static List<Event> getEventsByDate(boolean customEventOnly, Calendar startDate, Calendar endDate, String orderBy)
	{		
		SQLiteDatabase db = DataManager.getInstance(context).getReadableDatabase();
		Cursor cur  = db.query(
			EventDbConstants.TABLE_NAME,
			new String[]{
				EventDbConstants._ID,
				EventDbConstants.TITLE,
				EventDbConstants.DESC,
				EventDbConstants.LOCATION,
				EventDbConstants.IS_SINGLE,
				EventDbConstants.IS_CUSTOM,
				EventDbConstants.PRIORITY,
				EventDbConstants.START,
				EventDbConstants.END
			},
			
			EventDbConstants.START + " <= ? AND " + EventDbConstants.END + " >= ?" + (customEventOnly?(EventDbConstants.IS_CUSTOM + " = 1"):""), 
			new String[]
			{
				Long.valueOf(endDate.getTimeInMillis()).toString(),
				Long.valueOf(startDate.getTimeInMillis()).toString()
			},
			
			/*null,null,*/ null, null, orderBy);
		return extractEventFromCursor(db, cur);
	}
	
	public static Event getEventById(long id)
	{
		SQLiteDatabase db = DataManager.getInstance(context).getReadableDatabase();
		Cursor cur  = db.query(
			EventDbConstants.TABLE_NAME,
			new String[]{
				EventDbConstants._ID,
				EventDbConstants.TITLE,
				EventDbConstants.DESC,
				EventDbConstants.LOCATION,
				EventDbConstants.IS_SINGLE,
				EventDbConstants.IS_CUSTOM,
				EventDbConstants.PRIORITY,
				EventDbConstants.START,
				EventDbConstants.END
			},
			EventDbConstants._ID + " = ?", 
			new String[]
			{
				Long.valueOf(id).toString(),
			}, null, null, null);
		List<Event> events = extractEventFromCursor(db, cur);
		
		if (events.size() > 0)
		{
			return events.get(0);
		}
		else
		{
			return null;
		}
	}
	
	public static boolean updateEvent(Event event)
	{
		boolean success = false;
		
		long lastRowId;
		SQLiteDatabase db = DataManager.getInstance(context).getWritableDatabase();		
		
		ContentValues eventContent = new ContentValues();
		eventContent.put(EventDbConstants.TITLE, event.title);
		eventContent.put(EventDbConstants.DESC, event.description);
		eventContent.put(EventDbConstants.LOCATION, event.location);
		eventContent.put(EventDbConstants.IS_SINGLE, event.isSingleEvent ? 1 : 0);
		eventContent.put(EventDbConstants.IS_CUSTOM, event.isCustomEvent ? 1 : 0);
		eventContent.put(EventDbConstants.PRIORITY, event.priority);
		eventContent.put(EventDbConstants.START, event.singleDateTime.start.getTimeInMillis());
		eventContent.put(EventDbConstants.END, event.singleDateTime.end.getTimeInMillis());
		
		if (event._id < 0)
		{
			lastRowId = db.insert(EventDbConstants.TABLE_NAME, null, eventContent);
			event.setDatabaseId(lastRowId);
		}
		else
		{
			lastRowId = db.update(
					EventDbConstants.TABLE_NAME,
					eventContent, 
					EventDbConstants._ID + " = ?", 
					new String[]{Long.valueOf(event._id).toString()}
					);
		}
		

		
		if (lastRowId >= 0 )
		{
			db.delete(
					RecurrenceDbConstants.TABLE_NAME,
					RecurrenceDbConstants.EVENT_ID + " = ?",
					new String[]{Long.valueOf(lastRowId).toString()});
			success = true;
			if (!event.isSingleEvent)
			{
				for (Event.RecurrenceDateTime rec : event.recurrences)
				{
					ContentValues recurrenceContent = new ContentValues();
					recurrenceContent.put(RecurrenceDbConstants.EVENT_ID, event._id);
					recurrenceContent.put(RecurrenceDbConstants.START_DATE, rec.startDate.getTimeInMillis());
					recurrenceContent.put(RecurrenceDbConstants.END_DATE, rec.endDate.getTimeInMillis());
					recurrenceContent.put(RecurrenceDbConstants.DURATION, rec.eventDuration.getLongRep());
					recurrenceContent.put(RecurrenceDbConstants.DURATION_MONTH, rec.eventDuration.month);
					recurrenceContent.put(RecurrenceDbConstants.DURATION_YEAR, rec.eventDuration.year);
					recurrenceContent.put(RecurrenceDbConstants.PERIOD, rec.recurrencePeriod.getLongRep());
					recurrenceContent.put(RecurrenceDbConstants.PERIOD_MONTH, rec.recurrencePeriod.month);
					recurrenceContent.put(RecurrenceDbConstants.PERIOD_YEAR, rec.recurrencePeriod.year);
					db.insert(RecurrenceDbConstants.TABLE_NAME, null, recurrenceContent);
				}
			}
		}
		return success;
	}
	
	public static int removeEvent(Event event)
	{
		SQLiteDatabase db = DataManager.getInstance(context).getWritableDatabase();
		return db.delete(
				EventDbConstants.TABLE_NAME, 
				EventDbConstants._ID + " = ?", 
				new String[]{Long.valueOf(event._id).toString()}
			);
	}
	
	public static int removeAllEntries()
	{
		SQLiteDatabase db = DataManager.getInstance(context).getWritableDatabase();
		return db.delete(
				EventDbConstants.TABLE_NAME, 
				null, null
			);
	}
	
	private static List<Event> extractEventFromCursor(SQLiteDatabase db, Cursor cur)
	{
		List<Event> events = new ArrayList<Event>();
		if (cur.moveToFirst())
		do
		{
			long eventId = cur.getLong(cur.getColumnIndex(EventDbConstants._ID));
			String title = cur.getString(cur.getColumnIndex(EventDbConstants.TITLE));
			String desc = cur.getString(cur.getColumnIndex(EventDbConstants.DESC));
			String loc = cur.getString(cur.getColumnIndex(EventDbConstants.LOCATION));
			short priority = cur.getShort(cur.getColumnIndex(EventDbConstants.PRIORITY));
			boolean isSingleEvent = cur.getShort(cur.getColumnIndex(EventDbConstants.IS_SINGLE)) == 1;
			boolean isCustomEvent = cur.getShort(cur.getColumnIndex(EventDbConstants.IS_CUSTOM)) == 1;
			
			Calendar eventStartDate = Calendar.getInstance();
			eventStartDate.setTimeInMillis(cur.getLong(cur.getColumnIndex(EventDbConstants.START)));
			
			Calendar eventEndDate = Calendar.getInstance();
			eventEndDate.setTimeInMillis(cur.getLong(cur.getColumnIndex(EventDbConstants.END)));
						
			Event event = new Event(title,desc,loc,priority);
			event.setDatabaseId(eventId);
			Event.SingleEventDateTime sedt = event.new SingleEventDateTime(eventStartDate, eventEndDate);
			event.setSingleEventDateTime(sedt);
			
			List<RecurrenceDateTime> recs = new ArrayList<RecurrenceDateTime>();
			if (!isSingleEvent)
			{
				Cursor subCur = db.query(
					RecurrenceDbConstants.TABLE_NAME, 
					new String[]{
						RecurrenceDbConstants.EVENT_ID,
						RecurrenceDbConstants.START_DATE,
						RecurrenceDbConstants.END_DATE,
						RecurrenceDbConstants.DURATION,
						RecurrenceDbConstants.DURATION_MONTH,
						RecurrenceDbConstants.DURATION_YEAR,
						RecurrenceDbConstants.PERIOD,
						RecurrenceDbConstants.PERIOD_MONTH,
						RecurrenceDbConstants.PERIOD_YEAR,
					}, 
					"EVENT_ID = ?",
					new String[]
					{
						Long.valueOf(eventId).toString()
					},null, null, null);
				
				if (subCur.moveToFirst())
				do
				{
					Calendar recurrenceStartDate = Calendar.getInstance();
					recurrenceStartDate.setTimeInMillis(subCur.getLong(subCur.getColumnIndex(RecurrenceDbConstants.START_DATE)));
					
					Calendar recurrenceEndDate = Calendar.getInstance();
					recurrenceEndDate.setTimeInMillis(subCur.getLong(subCur.getColumnIndex(RecurrenceDbConstants.END_DATE)));
					
					Duration eventDuration = new Duration(subCur.getLong(subCur.getColumnIndex(RecurrenceDbConstants.DURATION)));
					eventDuration.setMonth(subCur.getInt(subCur.getColumnIndex(RecurrenceDbConstants.DURATION_MONTH)));
					eventDuration.setYear(subCur.getInt(subCur.getColumnIndex(RecurrenceDbConstants.DURATION_YEAR)));
					Duration recurrencePeriod = new Duration(subCur.getLong(subCur.getColumnIndex(RecurrenceDbConstants.PERIOD)));
					recurrencePeriod.setMonth(subCur.getInt(subCur.getColumnIndex(RecurrenceDbConstants.PERIOD_MONTH)));
					recurrencePeriod.setYear(subCur.getInt(subCur.getColumnIndex(RecurrenceDbConstants.PERIOD_YEAR)));
					
					Event.RecurrenceDateTime rdt = event.new RecurrenceDateTime(recurrenceStartDate, recurrenceEndDate, eventDuration, recurrencePeriod); 
					recs.add(rdt);
				} while (subCur.moveToNext());
			}
			event.setRecurrenceList(recs);
			event.setIsSingleEvent(isSingleEvent);
			event.isCustomEvent = isCustomEvent;
			events.add(event);
		} while (cur.moveToNext());
		return events;
	}
		
	public enum SortMethod
	{
		NAME, PRIORITY, DATETIME
	}
}
